Added rudimentary "xend reload" functionality. This allows you to reconfigure
authorEwan Mellor <ewan@xensource.com>
Mon, 4 Dec 2006 13:37:53 +0000 (13:37 +0000)
committerEwan Mellor <ewan@xensource.com>
Mon, 4 Dec 2006 13:37:53 +0000 (13:37 +0000)
the services offered by Xend, without restarting the daemon itself.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
tools/examples/init.d/xend
tools/misc/xend
tools/python/xen/xend/server/SrvDaemon.py
tools/python/xen/xend/server/SrvServer.py

index 8ad407637c6d7b98573479bb3bb971dd90b731d2..c12b1a0386374d886465281e64a648b696d5bc6f 100755 (executable)
@@ -36,7 +36,10 @@ case "$1" in
   status)
        xend status
        ;;
-  restart|reload|force-reload)
+  reload)
+        xend reload
+        ;;
+  restart|force-reload)
        xend restart
        await_daemons_up
        ;;
index b0ee27f5563eed0e3b169c08b877f8164c94fe8d..c35fbf00e0c827c1c6680425a8d517f98f13c00f 100644 (file)
@@ -109,7 +109,7 @@ def main():
     
     daemon = SrvDaemon.instance()
     if not sys.argv[1:]:
-        print 'usage: %s {start|stop|restart}' % sys.argv[0]
+        print 'usage: %s {start|stop|reload|restart}' % sys.argv[0]
     elif sys.argv[1] == 'start':
         if os.uname()[0] != "SunOS":
             start_xenstored()
@@ -123,6 +123,8 @@ def main():
         return daemon.start(trace=1)
     elif sys.argv[1] == 'stop':
         return daemon.stop()
+    elif sys.argv[1] == 'reload':
+        return daemon.reloadConfig()
     elif sys.argv[1] == 'restart':
         start_xenstored()
         start_consoled()
index 35c64869d41ac42cd8b8a9f87021f7ec6a474bbd..155062a704ec0061573a8f1ba4396b7f38a49c64 100644 (file)
@@ -60,6 +60,14 @@ class Daemon:
         return running
 
 
+    def reloadConfig(self):
+        """
+        """
+        pid = read_pid(XEND_PID_FILE)
+        if find_process(pid, XEND_PROCESS_NAME):
+            os.kill(pid, signal.SIGHUP)
+
+
     def status(self):
         """Returns the status of the xend daemon.
         The return value is defined by the LSB:
index f995a13bf9a49d11b298f6497cf91251ede76577..1b0ed9c0db0c52039df287869a203d2bc1da5d2c 100644 (file)
@@ -65,6 +65,7 @@ class XendServers:
     def __init__(self):
         self.servers = []
         self.cleaningUp = False
+        self.reloadingConfig = False
 
     def add(self, server):
         self.servers.append(server)
@@ -78,6 +79,11 @@ class XendServers:
             except:
                 pass
 
+    def reloadConfig(self, signum = 0, frame = None):
+        log.debug("SrvServer.reloadConfig()")
+        self.reloadingConfig = True
+        self.cleanup(signum, frame)
+
     def start(self, status):
         # Running the network script will spawn another process, which takes
         # the status fd with it unless we set FD_CLOEXEC.  Failing to do this
@@ -86,61 +92,71 @@ class XendServers:
             fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
         
         Vifctl.network('start')
-        threads = []
-        for server in self.servers:
-            thread = Thread(target=server.run, name=server.__class__.__name__)
-            if isinstance(server, HttpServer):
-                thread.setDaemon(True)
-            thread.start()
-            threads.append(thread)
-
-
-        # check for when all threads have initialized themselves and then
-        # close the status pipe
-
-        threads_left = True
-        while threads_left:
-            threads_left = False
-
-            for server in self.servers:
-                if not server.ready:
-                    threads_left = True
-                    break
-
-            if threads_left:
-                time.sleep(.5)
-
-        if status:
-            status.write('0')
-            status.close()
 
         # Prepare to catch SIGTERM (received when 'xend stop' is executed)
         # and call each server's cleanup if possible
         signal.signal(signal.SIGTERM, self.cleanup)
+        signal.signal(signal.SIGHUP, self.reloadConfig)
 
-        # Interruptible Thread.join - Python Bug #1167930
-        #   Replaces: for t in threads: t.join()
-        #   Reason:   The above will cause python signal handlers to be
-        #             blocked so we're not able to catch SIGTERM in any
-        #             way for cleanup
-        runningThreads = threads
-        while len(runningThreads) > 0:
-            try:
-                for t in threads:
-                    t.join(1.0)
-                runningThreads = [t for t in threads
-                                  if t.isAlive() and not t.isDaemon()]
-                if self.cleaningUp and len(runningThreads) > 0:
-                    log.debug("Waiting for %s." %
-                              [x.getName() for x in runningThreads])
-            except:
-                pass
-
-
-def create():
-    root = SrvDir()
-    root.putChild('xend', SrvRoot())
-    servers = XendServers()
+        while True:
+            threads = []
+            for server in self.servers:
+                thread = Thread(target=server.run, name=server.__class__.__name__)
+                if isinstance(server, HttpServer):
+                    thread.setDaemon(True)
+                thread.start()
+                threads.append(thread)
+
+
+            # check for when all threads have initialized themselves and then
+            # close the status pipe
+
+            threads_left = True
+            while threads_left:
+                threads_left = False
+
+                for server in self.servers:
+                    if not server.ready:
+                        threads_left = True
+                        break
+
+                if threads_left:
+                    time.sleep(.5)
+
+            if status:
+                status.write('0')
+                status.close()
+                status = None
+
+            # Interruptible Thread.join - Python Bug #1167930
+            #   Replaces: for t in threads: t.join()
+            #   Reason:   The above will cause python signal handlers to be
+            #             blocked so we're not able to catch SIGTERM in any
+            #             way for cleanup
+            runningThreads = threads
+            while len(runningThreads) > 0:
+                try:
+                    for t in threads:
+                        t.join(1.0)
+                    runningThreads = [t for t in threads
+                                      if t.isAlive() and not t.isDaemon()]
+                    if self.cleaningUp and len(runningThreads) > 0:
+                        log.debug("Waiting for %s." %
+                                  [x.getName() for x in runningThreads])
+                except:
+                    pass
+
+            if self.reloadingConfig:
+                log.info("Restarting all servers...")
+                self.cleaningUp = False
+                self.reloadingConfig = False
+                xroot.set_config()
+                self.servers = []
+                _loadConfig(self)
+            else:
+                break
+
+def _loadConfig(servers):
     if xroot.get_xend_http_server():
         servers.add(HttpServer(root,
                                xroot.get_xend_address(),
@@ -188,4 +204,11 @@ def create():
 
     if xroot.get_xend_unix_xmlrpc_server():
         servers.add(XMLRPCServer(XendAPI.AUTH_PAM))
+
+
+def create():
+    root = SrvDir()
+    root.putChild('xend', SrvRoot())
+    servers = XendServers()
+    _loadConfig(servers)
     return servers